package com.hc.controller;

import com.hc.domain.User;
import com.hc.service.UserService;
import com.hc.util.VerifyCodeUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/add")
    public String add(Model model) {
        return "user/add";
    }

    @RequestMapping("/update")
    public String update(Model model) {
        return "user/update";
    }

    @RequestMapping("/getVerifyCode")
    public void getVerifyCode(HttpSession session, HttpServletResponse response) throws IOException {
        //生成验证码
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        //验证码放入session
        session.setAttribute("verifyCode", verifyCode);
        //验证码存入图片
        response.setContentType("image/png");
        ServletOutputStream outputStream = response.getOutputStream();
        VerifyCodeUtils.outputImage(105, 45, outputStream, verifyCode);
    }

    @Resource
    private UserService userService;

    /**
     * 用户注册
     *
     * @param user  前端页面传过来的值
     * @param model
     * @return
     */
    @PostMapping("/regist")
    public String regist(User user, Model model) {
        try {
            userService.regist(user);
            return "index";
        } catch (Exception e) {
            e.printStackTrace();
            return "regist";
        }
    }

    /**
     * 用来处理身份认证
     *
     * @param username
     * @param password
     * @param model
     * @return
     */
    @PostMapping("/login")
    public String login(String username, String password, String verifyCode, boolean rememberMe, HttpSession session, Model model) {
        //判断用户名和密码为空
        if (StringUtils.isEmpty(username)||StringUtils.isEmpty(password)||StringUtils.isEmpty(verifyCode)){
            model.addAttribute("msg","用户名和密码不能为空！");
            return "login";
        }

        //比较验证码
        String verifyCode0 = (String) session.getAttribute("verifyCode");
        try {
            if (verifyCode0.equalsIgnoreCase(verifyCode)) {
                //获取当前的用户
                Subject subject = SecurityUtils.getSubject();
                //封装用户的登录数据
                UsernamePasswordToken token = new UsernamePasswordToken(username, password,rememberMe);
                //进行认证，认证时需要将用户名和密码封闭为token
                subject.login(token);
                return "index";
            } else {
                throw new RuntimeException("验证码错误");
            }
        } catch (UnknownAccountException e) { //用户名不存在
            model.addAttribute("msg", "用户名错误");
            return "login";
        } catch (IncorrectCredentialsException e) { //用户名不存在
            model.addAttribute("msg", "密码错误");
            return "login";
        } catch (LockedAccountException e){//账户锁定
            model.addAttribute("msg","账户被锁定！");
            return "login.html";
        }catch (RuntimeException e) {
            model.addAttribute("msg", "验证码错误");
            return "login";
        }
    }

    /**
     * 退出登录
     *
     * 使用 setMaxAge(int expiry)方法来设置Cookie的存在时间，参数expiry应是一个整数。正值表示cookie将在这
     * 么多秒以后失效。注意这个值是cookie将要存在的最大时间，而不是cookie现在的存在时间。 负值表示当浏览器关
     * 闭时，Cookie将会被删除。零值则是要删除该Cookie
     *
     * @param model
     * @return
     */
    @RequestMapping("/logout")
    public String lgout(Model model, HttpServletResponse response) {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {
            subject.logout();
            Cookie cookie = new Cookie("rememberMe", null);
            cookie.setMaxAge(0);
            response.addCookie(cookie);
        }
        return "index";
    }
}
